package com.juc.threadlocal;

import com.juc.threadpool.FixedThreadPoolTest;
import sun.misc.Unsafe;

import java.net.ServerSocket;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.LockSupport;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Consumer;

/**
 * @author mobai
 * @since 2021/3/8 11:33
 */
public class SimpleDateFormatTest {

    private static final ThreadLocal<SimpleDateFormat> SIMPLE_DATE_FORMAT_TEST = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SS"));

    public static void main(String[] args) {

        ExecutorService executorService = Executors.newFixedThreadPool(5);
        for (int i = 0; i < 5000; i++) {
            executorService.execute(() -> {
                Date date = new Date();
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(SIMPLE_DATE_FORMAT_TEST.get().format(date));
            });
        }


    }

    static class TaskQueue {
        private static final BlockingQueue<Integer> BLOCKING_QUEUE = new LinkedBlockingDeque<>(100);


        public void produce(Integer value) {
            try {
                while (true) {
                    BLOCKING_QUEUE.put(value);
                    System.out.println("当前线程" + Thread.currentThread().getName() + "生产了一条消息");
                }

            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }

        public void consume() {
            try {
                while (true) {
                    BLOCKING_QUEUE.take();
                    System.out.println("当前线程" + Thread.currentThread().getName() + "消费了一条消息");
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }


        public static void main(String[] args) {
            for (int i = 0; i < 4; i++) {
                final Integer value = i;
                TaskQueue taskQueue = new TaskQueue();
                Thread producer = new Thread(() -> taskQueue.produce(value), "生产者" + i);
                Thread consumer = new Thread(taskQueue::consume, "生产者" + i);
                producer.start();
                consumer.start();
            }
        }


    }

    /**
     *
     */
    static class MyLock {

        private volatile int state = 0;


        private static final long valueOffSet;

        static {
            try {
                valueOffSet = FixedThreadPoolTest.Calc.THE_UNSAFE.objectFieldOffset(MyLock.class.getDeclaredField("state"));
            } catch (NoSuchFieldException e) {
                throw new RuntimeException(e);
            }
        }

        public void lock() {
            while (!FixedThreadPoolTest.Calc.THE_UNSAFE.compareAndSwapInt(this, valueOffSet, 0, 1)) {

            }
        }

        public boolean tryLock() {
            return FixedThreadPoolTest.Calc.THE_UNSAFE.compareAndSwapInt(this, valueOffSet, 0, 1);
        }

        public void unlock() {
            state = 0;
        }

    }

    interface ISell {

        void sell(Book book) throws InterruptedException;

    }


    static class Miaosha implements ISell {

        private final MyLock myLock = new MyLock();

        @Override
        public void sell(Book book) throws InterruptedException {
            Thread.sleep(150);
            if (myLock.tryLock()) {
                if (book.getCount() > 0) {
                    book.setCount(0);
                    System.out.println(Thread.currentThread().getName() + "抢到了商品");

                } else {
                    System.out.println("没货了，草");
                }

                myLock.unlock();

            }else {
                System.out.println("没货了，草");
            }


        }

        public static void main(String[] args) {
            Book book = new Book();
            Miaosha miaosha = new Miaosha();
            ExecutorService executorService = Executors.newFixedThreadPool(100);
            for (int i = 0; i < 100; i++) {
                executorService.execute(() -> {
                    try {
                        miaosha.sell(book);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                });
            }

        }
    }


    static class Book {

        private volatile int count = 100;

        private MyLock myLock = new MyLock();


        public int getCount() {
            return count;
        }

        public void setCount(int count) {
            this.count = count;
        }

        public void sell() {
            if (count<=0){
                System.out.println("来迟了一步,干");
            }else{
                myLock.lock();
                try {
                    if (count > 0) {
                        count--;
                        System.out.println("线程" + Thread.currentThread().getName() + "买到书,还剩下" + count + "本书");
                    }
                } finally {
                    myLock.unlock();
                }
            }



        }

        public static void main(String[] args) {
            ExecutorService executorService = Executors.newFixedThreadPool(200);
            Book book = new Book();
            Runnable r = book::sell;
            for (int i = 0; i < 200; i++) {
                executorService.execute(r);
            }
            executorService.shutdown();

        }
    }

}
